package modelo.simulacion;

import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import modelo.mapeado.Coordinate;
import modelo.mapeado.CoordinateRangeException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import aglobex.web.server.PageKeyTree.Item;

public class RouteGoogle {

	private ArrayList<Step> recorrido;
	private String principio;
	private String medio;
	private String fin;
	private int step;
	
	public RouteGoogle(String beginning,String waypoint,String end) {
		
		recorrido = new ArrayList<Step>();
		principio = beginning;
		medio = waypoint;
		fin = end;
		step = 0;
		Document doc = getXMLRoute();
		getRouteElement(doc);
		//pintarRecorrido();
	}
	
	public ArrayList<Step> getRecorrido() {
		return recorrido;
	}

	public void setRecorrido(ArrayList<Step> recorrido) {
		this.recorrido = recorrido;
	}

	public String getPrincipio() {
		return principio;
	}

	public void setPrincipio(String principio) {
		this.principio = principio;
	}

	public String getFin() {
		return fin;
	}

	public void setFin(String fin) {
		this.fin = fin;
	}
	
	public void pintarRecorrido() {
		
		for (int i=0;i<recorrido.size();i++)
			System.out.println(recorrido.get(i).toString());
	}

	public Document getXMLRoute() {
		
		//String consulta = "http://maps.google.es/maps/api/directions/xml?origin=Ronda%20Buenavista," +
		//		"Toledo&destination=Madrid&sensor=false";
		String consulta = "http://maps.google.es/maps/api/directions/xml?origin="+principio
		+"&waypoints="+medio+"&destination="+fin+"&sensor=false";
		//String consulta = "http://maps.google.es/maps/api/directions/xml?origin=40.45057,-3.73194&waypoints=40.45025,-3.73237&destination=40.44076,-3.71392&sensor=false";
		System.out.println("Ruta: "+consulta);
    	URL url = null;
    	Document document = null;
		try {
			url = new URL(consulta);
			URLConnection conn = url.openConnection();
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	    	DocumentBuilder builder = factory.newDocumentBuilder();
	    	document = builder.parse(conn.getInputStream());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return document;
	}
	
	public void getRouteElement(Document documento) {
		
		Node nodo = documento.getDocumentElement();
    	NodeList lista = nodo.getChildNodes();
    	Integer cont = 0;
    	for (int i=0;i<lista.getLength();i++)
    		if (lista.item(i).getNodeName().equals("route")) {
    			lista = lista.item(i).getChildNodes();
	    		for (int j=0;j<lista.getLength();j++) {
	    			if (lista.item(j).getNodeName().equals("leg")) {
	    				cont = cont+1;
	    				if (cont > 1) {
	    					lista = lista.item(j).getChildNodes();
	    					for (int k=0;k<lista.getLength();k++)
	    						if (lista.item(k).getNodeName().equals("step")) {
	    							Node step = lista.item(k);
	    							Element elemento = (Element)step; 
	    							Step paso = generateStep(elemento);
	    							recorrido.add(paso);
	    						}
	    				}
	    			}
	    		}
    		}
	}
	
	public Step generateStep(Element elemento) {
		
		String instruccion = getTagValue("html_instructions",elemento);
		Integer pos = instruccion.indexOf("<");
		while (pos != -1) {
			String parte = instruccion.substring(0,pos);
			Integer fin = instruccion.indexOf(">");
			String siguiente = instruccion.substring(fin+1,instruccion.length());
			parte = parte.concat(siguiente);
			instruccion = parte;
			pos = instruccion.indexOf("<");
		}
		Coordinate start = getNodeValue("start_location",elemento);
		Coordinate end = getNodeValue("end_location",elemento);
		Step paso = new Step(start,end,instruccion);
		return paso;
	}
	
	public String getTagValue(String tag, Element elemento) {  
	    
		NodeList lista = elemento.getElementsByTagName(tag).item(0).getChildNodes();
		Node valor = (Node)lista.item(0);
		String resultado = new String(valor.getNodeValue());
		return resultado;
	
	}
	
	public Coordinate getNodeValue(String tag, Element elemento) {
		
		Double lat = null;
		Double lng = null;
		Coordinate resultado = null;
		NodeList lista = elemento.getElementsByTagName(tag).item(0).getChildNodes();
		for (int i=0;i<lista.getLength();i++) 
			if (lista.item(i).getNodeName().equals("lat")) {
				Node nodo = lista.item(i).getFirstChild();
				lat = new Double(nodo.getNodeValue());
			}
			else if (lista.item(i).getNodeName().equals("lng")) {
				Node nodo = lista.item(i).getFirstChild();
				lng = new Double(nodo.getNodeValue());
			}
		
		try {
			resultado = new Coordinate(lat,lng);
		} catch (CoordinateRangeException e) {
			e.printStackTrace();
		}
		return resultado;
	}
	
	public String getCurrentInstruction() {
		
		String resultado = "";
		if (step < recorrido.size()) 
			resultado = recorrido.get(step).getInstruccion();
		return resultado;
	}
	
	public Coordinate getCurrentStart() {
		
		Coordinate resultado = null;
		if (step < recorrido.size())
			resultado = recorrido.get(step).getOrigen();
		return resultado;
	}
	
	public Coordinate getCurrentFinish() {
		
		Coordinate resultado = null;
		if (step < recorrido.size())
			resultado = recorrido.get(step).getFin();
		return resultado;
	}
	
	public Boolean nextStep() {
		
		Boolean correcto = false;
		step = step+1;
		if (step < recorrido.size()) 
			correcto = true;
		return correcto;
	}

	public static void main(String[] args) {
	
		RouteGoogle ruta = new RouteGoogle("", "","");
	}
}
